package export

import (
	"game/game-design/loader"
	"sort"
	"strings"
)

// 工具运行期间收集到的配置表语言导出信息
type LanguageCollectingTable struct {
	className    string
	keySorts     []string //语言Key的顺序列表，用于按顺序导出语言表
	rows         map[string]*LanguageCollectingRow
	mergeSuffixs []string //存储需要合并语言表的后缀名
}

func NewLanguageCollectingTable(designFile *loader.DesignFile) *LanguageCollectingTable {
	//语言表原数据
	table := LanguageCollectingTable{}
	table.className = designFile.ClassName
	table.keySorts = make([]string, 0)
	table.rows = make(map[string]*LanguageCollectingRow)
	table.mergeSuffixs = make([]string, 0)

	for i, field := range designFile.Fields {
		_, ok := designFile.Langs[field.Name()]
		if !ok {
			continue
		}
		fieldName := field.Name()
		upperName := strings.ToUpper(fieldName[0:1]) + fieldName[1:]

		for _, rowDatas := range designFile.Datas {
			var langPos string
			if len(designFile.Indexes) > 0 {
				langPos = designFile.GetFirstIndexValue(rowDatas)
			} else {
				langPos = rowDatas[0]
			}
			langKey := designFile.ClassName + "_" + upperName + "_" + langPos
			langRow := LanguageCollectingRow{}
			langRow.key = langKey
			langRow.mergeDatas = make(map[string]string)
			if i >= len(rowDatas) {
				langRow.value = ""
			} else {
				langRow.value = rowDatas[i]
			}
			table.rows[langRow.key] = &langRow
			table.keySorts = append(table.keySorts, langKey)
		}
	}

	//语言表合并数据
	for i, field := range designFile.Fields {
		langMeta, ok := designFile.LangMerges[field.Name()]
		if !ok {
			continue
		}
		//被合并的列使用的语言key是#lang指令的列名
		table.mergeSuffixs = append(table.mergeSuffixs, langMeta.Suffix())
		mergeTo := langMeta.MergoTo()
		mergeName := strings.ToUpper(mergeTo[0:1]) + mergeTo[1:]

		for _, rowDatas := range designFile.Datas {
			var langPos string
			if len(designFile.Indexes) > 0 {
				langPos = designFile.GetFirstIndexValue(rowDatas)
			} else {
				langPos = rowDatas[0]
			}
			langKey := designFile.ClassName + "_" + mergeName + "_" + langPos
			langRow, ok := table.rows[langKey]
			if !ok {
				continue
			}
			if i >= len(rowDatas) {
				langRow.mergeDatas[langMeta.Suffix()] = ""
			} else {
				langRow.mergeDatas[langMeta.Suffix()] = rowDatas[i]
			}
		}
	}
	return &table
}

type LanguageCollectingRow struct {
	key        string
	value      string
	mergeDatas map[string]string //需要被合并的数据<后缀，值>
}

// 当前语言表中的数据记录
type LanguageCurrTable struct {
	fieldIdx map[string]int                //字段的下标索引
	groups   map[string]*LanguageCurrGroup //以类名进行的语言数据分组
}

// 当前表格中的语言数据
func NewLanguageCurrTable(langFile *loader.DesignFile) *LanguageCurrTable {
	table := LanguageCurrTable{}
	table.fieldIdx = make(map[string]int)
	for i, field := range langFile.Fields {
		table.fieldIdx[field.Name()] = i
	}

	table.groups = make(map[string]*LanguageCurrGroup)
	for _, rowData := range langFile.Datas {
		if rowData[0] == "" {
			continue
		}
		className := strings.Split(rowData[0], "_")[0]
		currGroup, ok := table.groups[className]
		if !ok {
			currGroup = &LanguageCurrGroup{}
			currGroup.className = className
			currGroup.rows = make(map[string]*LanguageCurrRow)
			currGroup.keySorts = make([]string, 0)
			table.groups[className] = currGroup
		}

		row := LanguageCurrRow{}
		row.langKey = rowData[0]
		row.langValue = rowData[1]
		row.datas = make([]string, len(langFile.Fields))
		for i := range langFile.Fields {
			if i >= len(rowData) {
				row.datas[i] = ""
			} else {
				row.datas[i] = rowData[i]
			}
		}
		currGroup.rows[row.langKey] = &row
		currGroup.keySorts = append(currGroup.keySorts, row.langKey)
	}
	return &table
}

func (t *LanguageCurrTable) fromResultData() [][]string {
	//构建最后的导出数据
	resultLangs := make([][]string, 0, 2000)
	fileSorts := make([]string, 0, 100)
	for key := range t.groups {
		fileSorts = append(fileSorts, key)
	}
	sort.Strings(fileSorts)
	for _, fileSort := range fileSorts {
		currGroup := t.groups[fileSort]
		for _, key := range currGroup.keySorts {
			currRow := currGroup.rows[key]
			resultLangs = append(resultLangs, currRow.datas)
		}
	}
	return resultLangs
}

type LanguageCurrGroup struct {
	className string                      //类名
	rows      map[string]*LanguageCurrRow //行数据的映射
	keySorts  []string                    //语言键的读表顺序
}

type LanguageCurrRow struct {
	langKey   string   //语言键
	langValue string   //语言键对应的原始值
	datas     []string //本行的原始数据
}

func NewLanguageCurrRow(collectingRow *LanguageCollectingRow, currTable *LanguageCurrTable, dataSize int, oldRow *LanguageCurrRow) *LanguageCurrRow {
	newRow := LanguageCurrRow{}
	newRow.langKey = collectingRow.key
	newRow.langValue = collectingRow.value
	newRow.datas = make([]string, dataSize)
	if oldRow != nil {
		//将旧数据填充回新的行内，如果被合并的列不是通过#langmerge进行合并的，则需要保留原来人工填写的内容
		for i, oldValue := range oldRow.datas {
			if i < len(newRow.datas) {
				newRow.datas[i] = oldValue
			}
		}
	}
	newRow.datas[0] = collectingRow.key
	newRow.datas[1] = collectingRow.value
	//将合并数据填充到指定的列中
	for suffix, mergeData := range collectingRow.mergeDatas {
		idx := currTable.fieldIdx["ori"+suffix]
		newRow.datas[idx] = mergeData
	}
	return &newRow
}
